package frame.project;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ScrollView;
import android.widget.TextView;

public class Main extends Activity {
	Button btnCamera,btnSetting,btnAlbum, btnEditPhoto, btnImport;
	ImageView imgBtn, btnAll, imgIndicator;
	TextView textIndicator;
	ScrollView scroll;
	LinearLayout layoutScroll, layout, outLayout, outText;
	ProgressDialog dialog;

	Cursor cursor;
	Bitmap bm;
	ImageProduce image = new ImageProduce();
	DBAdapter db = new DBAdapter(this);
	long maxDate = 0,date;
	Bundle bundle;
	boolean pause = false;
	int layoutHeight, layoutWidth, allHeight, allWidth, imageHeight, imageWidth, indicHeight, indicWidth;
	ImageDetails imgDetails;
	
	String pathFirst;
	
	// Collection of images number in each label
	String[] labelPath = new String[7];
	
	String[] labelTitle = new String[7];
	
	// Collection of color names
	String[] labelColor = {"Red", "Orange", "Yellow", "Green", "Blue", "Pink", "Purple"};
	
	int[] labelIndicator = {R.drawable.indicator_red, R.drawable.indicator_orange, R.drawable.indicator_yellow, R.drawable.indicator_green,
							R.drawable.indicator_blue, R.drawable.indicator_pink, R.drawable.indicator_purple};
	
	/**
	 * Check if any of the labels are currently being used.
	 * For example, if red label has one or more picture labeled with it, then increase counter
	 * @author Marcel
	 */
	public void checkLabel(){
		String label = null;
		
		db.open();
		Cursor c = db.getPath();
		c.moveToFirst();

		for (int x = 0; x < c.getCount(); x++){
			
			// Get path from the first image in the database
			if (pathFirst == null){
				pathFirst = c.getString(1).toString();
			}
			
			// Get current image's label
			label = c.getString(3).toString();
			
			// Compare, if the label is not neutral
			if (label.equals("Neutral") == false){
				
				// Check matching color index
				for (int y = 0; y < labelColor.length; y++){
					
					// Get the path of the first image of the matched label 
					if (labelColor[y].equals(label) && labelPath[y] == null){
						labelPath[y] = c.getString(1).toString();
						cursor = db.getLabel();
						cursor.moveToPosition(y);
						
						labelTitle[y] = cursor.getString(1).toString();
						break;
					}
				}	
			}
			
			c.moveToNext();
		}
		db.close();
		
		addButtons();
	}
	
	/**
	 * If any of the counters are more than 0, create an outer layout with  a layout and indicator inside
	 * The layout contains a button inside it
	 * Layout is used to give a frame background
	 * @author Marcel
	 */
	public void addButtons(){
		
		// Layout size
		layoutHeight = getPixel(180);
		layoutWidth = getPixel(150);

		// btnAll size
		allHeight = getPixel(200) - 30;
		allWidth = getPixel(150) - 40;
		
		// Image's size
		imageHeight = layoutHeight - 30;
		imageWidth = layoutWidth - 40;

		// Indicator's size
		indicHeight = getPixel(10);
		indicWidth = layoutWidth;

		layoutScroll = (LinearLayout) findViewById(R.id.scrollAlbum);

		// Most outer layout
		LinearLayout.LayoutParams outerParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		outerParams.gravity = Gravity.CENTER;
		
		// LayoutParams for layout 
		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(layoutWidth, layoutHeight);
		layoutParams.setMargins(20, 0, 20, 0);
		layoutParams.gravity = Gravity.CENTER;
		
		// Layout to hold textview - so that the text view will be able to be displayed on center
		LinearLayout.LayoutParams outerTextParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		outerTextParams.gravity = Gravity.CENTER;
				
		// LayoutParams for btnAll
		LinearLayout.LayoutParams allParams = new LinearLayout.LayoutParams(allWidth, allHeight);
		layoutParams.setMargins(20, 15, 20, 0);
		
		// LayoutParams for image
		LinearLayout.LayoutParams imageParams = new LinearLayout.LayoutParams(imageWidth, imageHeight);
		imageParams.setMargins(20 , 15, 20, 0);
		
		// LayoutParams for indicator
		LinearLayout.LayoutParams indicatorParams = new LinearLayout.LayoutParams(indicWidth, indicHeight);
		indicatorParams.setMargins(0, 20, 0, 0);
		indicatorParams.gravity = Gravity.CENTER;
		
		// Check if the database has some images, check its path, and show it
		// This is for all pictures album, the pre-defined album
		try{
			bm = image.decodeBitmap(pathFirst, 200, 200);
			btnAll.setLayoutParams(allParams);
			btnAll.setBackgroundDrawable(new BitmapDrawable(getResources(), bm));
		}catch (Exception e){
			
		}

		for (int x = 0; x < labelPath.length; x++){

			// Check if labelPath of x is currently null, meaning that it has some images labeled with it
			if (labelPath[x] != null){
				// Defines outer layout
				outLayout = new LinearLayout(this);
				outLayout.setOrientation(1);
				outLayout.setLayoutParams(outerParams);
				
				// Define outer layout for textIndicator
				outText = new LinearLayout(this);
				outText.setLayoutParams(outerTextParams);
				
				// Define the text view as the album title
				textIndicator = new TextView(this);
				textIndicator.setTextColor(Color.WHITE);
				textIndicator.setText(labelTitle[x]);
				
				// Defines a layout, the purpose of this layout is to add a frame image behind the cover image
				layout = new LinearLayout(this);
				layout.setLayoutParams(layoutParams);
				// Set the frame image
				layout.setBackgroundDrawable(getResources().getDrawable(R.drawable.frame));
				
				// Defines an image for the image's cover
				imgBtn = new ImageView(this);
				imgBtn.setLayoutParams(imageParams);
				imgBtn.setOnClickListener(new ListenerAlbumBtn(labelColor[x]));
				imgBtn.setScaleType(ScaleType.CENTER_INSIDE);
				
				// Get cover image's bitmap from the path
				bm = image.decodeBitmap(labelPath[x], 200, 200);
				
				// Set the cover image
				imgBtn.setBackgroundDrawable(new BitmapDrawable(getResources(),bm));
				
				// Defines the indicator
				// The purpose of indicator is to indicates which label the album is for.
				imgIndicator = new ImageView(this);
				imgIndicator.setBackgroundResource(labelIndicator[x]);
				imgIndicator.setLayoutParams(indicatorParams);
				
				// Adds the cover image to the layout
				layout.addView(imgBtn);
				
				// Adds the textIndicator (title) to its layout
				outText.addView(textIndicator);
				
				// Adds layout and the indicator to the outerlayout
				outLayout.addView(outText);
				outLayout.addView(layout);
				outLayout.addView(imgIndicator);
				
				// finally, adds the outer layout to the scroll layout
				layoutScroll.addView(outLayout);
			}
		}	
	}
	
	/**
	 * Check if the current image object's date modified is bigger than the latest date modified,
	 * means that the image is a new image. thus, add to database
	 * @param image - ImageDetails object, which stores image's path and date modified
	 * @author Marcel
	 */
    public void insertPath(ImageDetails image, int index){
    	String path = image.getPath();
    	long date = image.getDate();
    	
    	if (date > maxDate){
    		db.open();
    		Cursor cur = db.getPath();
    		
    		// Stores as a string, to prevent out of bound
    		db.insertPath(path, Long.toString(date), "Neutral", "Description..", cur.getCount());
    		db.close();
    	}
    }
    
    /**
     * Check the latest date modified as a comparator for importing new images
     * @author Marcel
     * 
     */
    public void getMaxDate(){
    		db.open();
        	Cursor c = db.getPath();
        	c.moveToFirst();
        	if (c.getCount() > 0){
        		maxDate = Long.parseLong(c.getString(2));
        	}else{
        		maxDate = 0;
        	}
        	db.close();
    }
    
    /**
	 * Converts dp to pixels
	 * @param dp - the required value of dp
	 * @return the converted pixels
	 */
	public int getPixel(int dp){
		float pix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
		int pixel = Math.round(pix);
		return pixel;
	}

	/**
     * ImageDetails object, stores image's path and image's date modified
     * @author Marcel
     *
     */
    public class ImageDetails{
    	String path;
    	long date;
    	
    	public ImageDetails(String path, long date){
    		this.path = path;
    		this.date = date;
    	}
    	
    	public String getPath(){
    		return this.path;
    	}
    	
    	public long getDate(){
    		return this.date;
    	}
    }
    
    /**
     * Thread used to import images
     * Runs in background 
     * Shows loading indicator
     * @author Marcel, Jourdan
     *
     */
	class Imports extends AsyncTask<Object, Integer , Object> {
	    /**
	     * Load images from SD Card in the background
	     *  
	     * @see android.os.AsyncTask#doInBackground(Params[])
	     */
		@SuppressWarnings("deprecation")
		@Override
	    protected void onPreExecute() {
	        super.onPreExecute();
	        showDialog(0);
	    }
		
	    protected Object doInBackground(Object... params) {
	    	getMaxDate();
	    	
	        // Set up an array of the Title Image ID column we want
	        String[] mProjection = {
	        		MediaStore.Images.ImageColumns._ID,
	        		MediaStore.Images.ImageColumns.DATA,
	        		MediaStore.Images.ImageColumns.DATE_MODIFIED};
	        // Create the cursor pointing to the SDCard
	        @SuppressWarnings("deprecation")
			Cursor cursor = managedQuery( 
	        		MediaStore.Images.Media.EXTERNAL_CONTENT_URI,	//The URI of the content provider to query
	                mProjection,									//List of columns to return
	                null,											//SQL WHERE clause
	                null,											//The arguments to selection, if any ?s are pesent
	                null);											//SQL ORDER BY clause
	        
	        int indexPath = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA);
	        int indexDate = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATE_MODIFIED);
	        
	        int size = cursor.getCount();

	        String imagePath = "";
	        long imageDate = 0;
	        
	        
	       dialog.setMax(size);
	        
	        for (int i = 0; i < size; i++) {
	            // Move to next cursor
	            cursor.moveToPosition(i);

	            publishProgress(Math.round(i));
	            
	        	// Gets image's path
	            imagePath = cursor.getString(indexPath);
	            
	            // Gets image's date modified
	            imageDate = cursor.getLong(indexDate);
	            
	            // Stores in ImageDetails object
	            imgDetails = new ImageDetails(imagePath, imageDate);
	            
	            // Insert ImageDetails object to database
	            insertPath(imgDetails, i);
	            
	        }
	        return null;
	    }
	    /**
	     * If we have finished storing each item, increase the loading indicator
	     * @param value - percentage of finished item 
	     */
	    @Override
	    public void onProgressUpdate(Integer... value) {
	    	dialog.setProgress(value[value.length - 1]);
	    }
	    
	    /**
	     * Called once all the task has been done
	     * Close loading dialog indicator
	     */
	    @Override
	    protected void onPostExecute(Object result) {
	    	dismissDialog(0);
	    	reload();
	    }
	}

	/**
	 * Listener class for each button generated dynamically through addButtons() method
	 * Opens album, containing only the images that are labeled with that label
	 * @author Marcel
	 *
	 */
	public class ListenerAlbumBtn implements View.OnClickListener{
		String color;
		
		public ListenerAlbumBtn(String color){
			this.color = color;
		}
		
		public void onClick(View v) {
			Intent intent = new Intent(getApplicationContext(), AlbumCustom.class);
			Bundle bundle = new Bundle();
			bundle.putString("color", color);
			intent.putExtras(bundle);
			startActivity(intent);
		}
		
	}

	/**
	 * OnResume handles activity after pausing, and check if it was paused previously
	 * If the activity was paused, reload the page
	 */
	@Override
	public void onResume(){
		super.onResume();
		if (pause == true){
			reload();
			pause = false;
		}
	}
	
	/**
	 * Handles activity when the activity is not available (go to paused state)
	 */
	@Override
	public void onPause(){
		super.onPause();
		pause = true;
	}
	
	/**
	 * OnCreate dialog for progress dialog box 
	 */
	@Override
	protected Dialog onCreateDialog(int id) {
	    switch (id) {
	    case 0:
	        dialog = new ProgressDialog(this);
	        
	        dialog.setMessage("Importing Images. Please wait...");
	        dialog.setIndeterminate(false);
	        
	        // Sets max percentage
	        //dialog.setMax(100);
	        
	        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
	        dialog.setCancelable(false);
	        
	        // Shows the progress dialog box
	        dialog.show();
	        return dialog;
	    default:
	        return null;
	    }
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
	
	    btnCamera = (Button) findViewById(R.id.btnCamera);
	    btnSetting = (Button) findViewById(R.id.btnSetting);
	    btnAlbum = (Button) findViewById(R.id.btnGallery);
	    btnEditPhoto = (Button) findViewById(R.id.btnEditPhoto);
	    btnImport = (Button) findViewById(R.id.btnImport);
	    btnAll = (ImageView) findViewById(R.id.btnAll);
	    
	    //activate camera feature
	    //opens camera class
	    btnCamera.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent i = new Intent(getApplicationContext(), Camera.class);
				startActivity(i);
			}
		});
	    
	    //activate setting
	    //opens setting class
	    btnSetting.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
				Intent i = new Intent(getApplicationContext(),Setting.class);
				startActivity(i);
			}
		});
	    
	    //activate album feature
	    //opens album class
	    btnAlbum.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent i = new Intent(getApplicationContext(),AlbumCustom.class);
				startActivity(i);
				checkLabel();
			}
		});
	    
	    //activate edit picture feature
	    //opens EditPicture class
	    btnEditPhoto.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent i = new Intent(getApplicationContext(), Edit.class);
				startActivity(i);
			}
		});
	    
	    //activate import feature
	    //opens Import class
	    btnImport.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				new Imports().execute();
			}
		});
	    
	    btnAll.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				Intent i = new Intent(getApplicationContext(), AlbumCustom.class);
				startActivity(i);
			}
		});
	
	    checkLabel();
	}
	
	
	public void reload() {	    
		Intent intent = getIntent();
	    overridePendingTransition(0, 0);
	    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
	    finish();

	    overridePendingTransition(0, 0);
	    startActivity(intent);
	}
  }